home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_casm / pcl4c60.zip / SELF32.C < prev    next >
Text File  |  1996-10-22  |  10KB  |  349 lines

  1. /*
  2. **                ---  selftest.c ---
  3. **
  4. **  32-bit DPMI version
  5. **
  6. **  SELFTEST requires two serial ports on the same computer. The
  7. **  program transmits a test string on one port (FirstCOM) and
  8. **  receives on a second port (SecondCOM), where the two ports are
  9. **  connected via a null modem adapter. The received string is tested
  10. **  against the transmit string (they should be identical).
  11. **
  12. **  Connect the two serial ports (on a single computer) together
  13. **  using a null modem cable. Be sure to modify the configuration
  14. **  section for non-standard PC ports or to setup your multiport
  15. **  board. Note that many multiport boards are either Digiboard or
  16. **  BOCA board compatible.
  17. **
  18. **  IMPORTANT: You may have to modify the port address & IRQ to match
  19. **  your Digiboard or BOCA board installation.
  20. **
  21. */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. #include "pcl4c32.h"
  28. #include "sioerr32.h"
  29.  
  30. #define ESC 0x1b
  31. #define CR  0x0d
  32. #define LF  0x0a
  33. #define ONE_SECOND 18
  34.  
  35. #define PC 1
  36. #define DB 2
  37. #define BB 3
  38.  
  39. /*** Global Variables ***/
  40.  
  41. #define TEST_SIZE 63
  42.  
  43. char LastRxChar = '\0';
  44. char TestSet[TEST_SIZE];
  45. int  NbrRuns = 16;
  46. int  TestLength;
  47. int  FirstCOM;
  48. int  SecondCOM;
  49.  
  50. int MultiUART = 0;
  51. int MultiIRQ = 0;
  52. int MultiStatus = 0;
  53.  
  54. void AllDone(int);
  55. void Display(int);
  56. void CheckAlloc(int,char *);
  57. int  ErrorCheck(int);
  58. int  AllocSel(int);
  59. int  BaudMatch(char *);
  60. void CheckOverrun(int);
  61. void ShowStats(int);
  62.  
  63. static int  RxSeg1 = 0;
  64. static int  TxSeg1 = 0;
  65. static int  RxSeg2 = 0;
  66. static int  TxSeg2 = 0;
  67.  
  68. /* standard PC port configuration */
  69.  
  70. static int StdAdrPC[4] = {0x3f8,0x2f8,0x3e8,0x2e8};
  71. static int StdIrqPC[4] = {4,3,4,3};
  72. static int BaudCode;
  73. static char *BaudRate[10] =  {"300","600","1200","2400","4800","9600",
  74.                               "19200","38400","57600","115200"};
  75. static int Selection = 0;  /* PC, DB, or BB */
  76.  
  77. void main(int argc, char *argv[])
  78. {int Port;
  79.  char *P;
  80.  int ComLimit = 0;
  81.  char c;
  82.  int Version;
  83.  int i, n, rc;
  84.  int RxQue;
  85.  int TxQue;
  86.  if(argc!=5)
  87.   {printf("Usage: self32 {pc|db|bb} 1stCom 2ndCom baudrate\n");
  88.    exit(1);
  89.   }
  90.  BaudCode = BaudMatch(argv[4]);
  91.  if(BaudCode==-1)
  92.    {printf("Bad baud rate '%s'\n",argv[4]);
  93.     exit(1);
  94.    }
  95.  P = argv[1];
  96.  if((strcmp(P,"pc")==0)||(strcmp(P,"PC")==0)) Selection = PC;
  97.  if((strcmp(P,"db")==0)||(strcmp(P,"DB")==0)) Selection = DB;
  98.  if((strcmp(P,"bb")==0)||(strcmp(P,"BB")==0)) Selection = BB;
  99.  if(Selection==0)
  100.    {puts("Must specify 'PC', 'DB' or 'BB' as 1st argument");
  101.     puts("EG:  SELF32 PC 1 4 38400");
  102.     exit(1);
  103.    }
  104.  /* set port limit to 4 ports (shareware version) */
  105.  if(Selection==PC) ComLimit = COM4;
  106.  if(Selection==DB) ComLimit = COM4;
  107.  if(Selection==BB) ComLimit = COM4;
  108.  FirstCOM = atoi(argv[2]) -1;
  109.  SecondCOM = atoi(argv[3]) -1;
  110.  printf("FirstCOM  = COM%d\n",1+FirstCOM);
  111.  printf("SecondCOM = COM%d\n",1+SecondCOM);
  112.  if(FirstCOM<COM1)
  113.    {puts("1stCom must be >= COM1");
  114.     exit(1);
  115.    }
  116.  if(SecondCOM>ComLimit)
  117.    {printf("2ndCom must be <= COM%d\n",1+ComLimit);
  118.     exit(1);
  119.    }
  120.  
  121.  if(Selection==DB)
  122.    {/*** Custom Configuration: DigiBoard PC/8 ***/
  123.     MultiUART = 0x180; MultiIRQ = IRQ5; MultiStatus = 0x1C0;
  124.     printf("[ Configuring DigiBoard as COM1-COM%d (IRQ%d) @ 0x%x ]\n",
  125.        1+ComLimit,MultiIRQ,MultiUART);
  126.     ErrorCheck( SioPorts(1+ComLimit,COM1,MultiStatus,DIGIBOARD) );
  127.     for(Port=COM1;Port<=ComLimit;Port++)
  128.       {/* set DigiBoard UART addresses */
  129.        ErrorCheck( SioUART(Port,MultiUART+8*Port) );
  130.        /* set DigiBoard IRQ */
  131.        ErrorCheck( SioIRQ(Port,MultiIRQ) );
  132.       }
  133.    }
  134.  if(Selection==BB)
  135.    {/*** Custom Configuration: BOCA BB2016 ***/
  136.     MultiUART = 0x100; MultiIRQ = IRQ10; MultiStatus = MultiUART + 7;
  137.     printf("[ Configuring BOCA Board as COM1-COM%d (IRQ%d) @ 0x%x ]\n",
  138.        1+ComLimit,MultiIRQ,MultiUART);
  139.     ErrorCheck( SioPorts(1+ComLimit,COM1,MultiStatus,BOCABOARD) );
  140.     for(Port=COM1;Port<=ComLimit;Port++)
  141.       {/* set BOCA Board UART addresses */
  142.        ErrorCheck( SioUART(Port,MultiUART+8*Port) );
  143.        /* set BOCA Board IRQ */
  144.        ErrorCheck( SioIRQ(Port,MultiIRQ) );
  145.       }
  146.    }
  147.  
  148.  if(Selection==PC)
  149.    {/*** Standard Configuration: 4 port card ***/
  150.     puts("[ Configuring for PC ]");
  151.     for(i=COM1;i<=COM4;i++)
  152.       {SioUART(i,StdAdrPC[i]);
  153.        SioIRQ(i,StdIrqPC[i]);
  154.       }
  155.    }
  156.  
  157.  ErrorCheck( SioRxBuf(FirstCOM,0,Size1024) );
  158.  ErrorCheck( SioTxBuf(FirstCOM,0,Size1024) );
  159.  if(FirstCOM!=SecondCOM)
  160.    {ErrorCheck( SioRxBuf(SecondCOM,0,Size1024) );
  161.     ErrorCheck( SioTxBuf(SecondCOM,0,Size1024) );
  162.    }
  163.  
  164.  /* set port parmameters */
  165.  ErrorCheck( SioParms(FirstCOM,NoParity,OneStopBit,WordLength8) );
  166.  if(FirstCOM!=SecondCOM) ErrorCheck( SioParms(SecondCOM,NoParity,OneStopBit,WordLength8) );
  167.  /* reset the ports */
  168.  printf("Resetting COM%d\n",1+FirstCOM);
  169.  ErrorCheck( SioReset(FirstCOM,BaudCode) );
  170.  if(FirstCOM!=SecondCOM)
  171.    {printf("Resetting COM%d\n",1+SecondCOM);
  172.     ErrorCheck( SioReset(SecondCOM,BaudCode) );
  173.    }
  174.  printf("***\n");
  175.  printf("*** SELF32 1.0\n");
  176.  printf("***\n");
  177.  Version = SioInfo('V');
  178.  printf("*** Lib Ver : %d.%d\n",Version/16,Version%16);
  179.  
  180.  /* display port info */
  181.  Display(FirstCOM);
  182.  if(FirstCOM!=SecondCOM) Display(SecondCOM);
  183.  printf("***\n");
  184.  
  185.  printf("Starting @ %s baud. COM%d to COM%d\n",argv[4],FirstCOM+1,SecondCOM+1);
  186.  
  187.  /* build TestSet[] array */
  188.  for(i=0;i<26;i++) TestSet[i] = 'A'+i;
  189.  for(i=0;i<26;i++) TestSet[26+i] = 'a'+i;
  190.  for(i=0;i<10;i++) TestSet[52+i] = '0'+i;
  191.  TestSet[62] = '\n';
  192.  /* clear all buffers */
  193.  SioDTR(FirstCOM,'S');
  194.  SioRxClear(FirstCOM);
  195.  SioTxClear(FirstCOM);
  196.  if(FirstCOM!=SecondCOM)
  197.    {SioDTR(SecondCOM,'S');
  198.     SioRxClear(SecondCOM);
  199.     SioTxClear(SecondCOM);
  200.    }
  201.  
  202.  printf("Test Set: %s",TestSet);
  203.  /* send test sets */
  204.  printf("\n  Sending set: ");
  205.  for(i=0;i<NbrRuns;i++)
  206.    {/* send test set again */
  207.     printf("%d ",i);
  208. #if 1
  209.     for(n=0;n<TEST_SIZE;n++)
  210.       {c = TestSet[n];
  211.        rc = SioPutc(FirstCOM,c);
  212.        if(rc<0)
  213.           {printf("Error %d transmitting '%c' (n=%d)\n",rc,c,n);
  214.            SioError(rc);
  215.            AllDone(1);
  216.           }
  217.       }
  218. #else
  219.     SioPuts(FirstCOM,&TestSet[0],TEST_SIZE);
  220. #endif
  221.    }
  222.  printf("\n  [TxQue = %d bytes; RxQue = %d bytes]",SioTxQue(FirstCOM),SioRxQue(SecondCOM));
  223.  /* receive test sets */
  224.  printf("\nReceiving set: ");
  225.  for(i=0;i<NbrRuns;i++)
  226.    {/* receive set again */
  227.     printf("%d ",i);
  228.     /* receive next test set */
  229.     for(n=0;n<TEST_SIZE;n++)
  230.       {/* fetch next byte */
  231.        rc = SioGetc(SecondCOM,ONE_SECOND);
  232.        if(rc<0)
  233.          {/* get queue size snapshot immediately */
  234.           TxQue = SioTxQue(FirstCOM);
  235.           RxQue = SioRxQue(SecondCOM);
  236.           /* display error message */
  237.           printf("\nERROR: %d bytes received, LastRxChar=%c [%xH]: ",
  238.                  i*TEST_SIZE+n,LastRxChar,LastRxChar);
  239.           SioError(rc);
  240.           CheckOverrun(FirstCOM);
  241.           if(FirstCOM!=SecondCOM) CheckOverrun(SecondCOM);
  242.           printf("Regs: "); for(i=0;i<7;i++) printf("%x ",SioRead(SecondCOM,i) );
  243.           printf("\n");
  244.           printf("%d bytes left in COM%d TX queue\n", TxQue,1+FirstCOM );
  245.           printf("%d bytes left in COM%d RX queue\n", RxQue,1+SecondCOM );
  246.           printf("%d system callbacks\n", SioInfo('s') );  /* ????? */
  247.           ShowStats(FirstCOM);
  248.           if(FirstCOM!=SecondCOM) ShowStats(SecondCOM);
  249.           AllDone(2);
  250.          }
  251.        /* compare character */
  252.        LastRxChar = (char)rc;
  253.        if(LastRxChar!=TestSet[n])
  254.          {/* characters don't match ! */
  255.           printf("\nERROR: Received '%c'(0x%x), expected '%c'(0x%x) at n=%d\n",
  256.             LastRxChar,LastRxChar,TestSet[n],TestSet[n],n);
  257.           printf("%d bytes in COM%d TX queue\n", SioTxQue(FirstCOM),1+FirstCOM );
  258.           printf("%d bytes in COM%d RX queue\n", SioRxQue(SecondCOM),1+SecondCOM );
  259.           ShowStats(FirstCOM);
  260.           ShowStats(SecondCOM);
  261.           CheckOverrun(FirstCOM);
  262.           if(FirstCOM!=SecondCOM) CheckOverrun(SecondCOM);
  263.           AllDone(3);
  264.          }
  265.       }
  266.    } /* end for */
  267.  printf("\n\n");
  268.  /* check RX FIFO */
  269.  TestLength = NbrRuns * TEST_SIZE;
  270.  
  271.  i = SioStats(SecondCOM,'R');
  272.  printf("%3d RX interrupts on %d incoming bytes: ", i,TestLength);
  273.  if(i<TestLength) puts("RX FIFO is operational");
  274.  else puts("RX FIFO is NOT operational [or not 16550 UART]");
  275.  if(SioInfo('I'))
  276.    {/* check TX FIFO */
  277.     i = SioStats(FirstCOM,'T');
  278.     printf("%3d TX interrupts on %d outgoing bytes: ", i,TestLength);
  279.     if(i<TestLength) puts("TX FIFO is operational");
  280.     else puts("TX FIFO is NOT operational [or not 16550 UART]");
  281.    }
  282.  ShowStats(FirstCOM);
  283.  CheckOverrun(FirstCOM);
  284.  if(FirstCOM!=SecondCOM)
  285.    {ShowStats(SecondCOM);
  286.     CheckOverrun(SecondCOM);
  287.    }
  288.  printf("\n*** SUCCESS: Test AOK !\n\n");
  289.  AllDone(0);
  290. } /* end main */
  291.  
  292. int ErrorCheck(int Code)
  293. {int DpmiCode;
  294.  /* trap PCL error codes */
  295.  if(Code<0)
  296.      {printf("ERROR: ");
  297.       SioError(Code);
  298.       AllDone(0-Code);
  299.      }
  300.  return(0);
  301. } /* end ErrorCheck */
  302.  
  303.  
  304. void Display(int Port)
  305. {printf("***    COM%d : ",1+Port);
  306.  if(Selection==PC) printf("Adr=%3x IRQ=%d",StdAdrPC[Port],StdIrqPC[Port]);
  307.  else printf("Adr=%3xh IRQ=%d Status=%xh",MultiUART+8*(Port-COM1),MultiIRQ,MultiStatus);
  308.  /* enable FIFO (if 16550) */
  309.  if( SioFIFO(Port,LEVEL_8) ) printf(" [16550]\n");
  310.  else printf(" [8250/16450]\n");
  311. }
  312.  
  313. void AllDone(int Code)
  314. {
  315.  printf("Shutting down COM%d\n",1+FirstCOM);
  316.  SioDone(FirstCOM);
  317.  if(FirstCOM!=SecondCOM)
  318.    {printf("Shutting down COM%d\n",1+SecondCOM);
  319.     SioDone(SecondCOM);
  320.    }
  321.  exit(Code);
  322. }
  323.  
  324. void CheckAlloc(int Seg,char *Msg)
  325. {if(Seg==0)
  326.   {printf("Cannot allocate memory for %s\n",Msg);
  327.    AllDone(5);
  328.   }
  329. }
  330.  
  331. int BaudMatch(char *P)
  332. {int i;
  333.  /* find baud rate in table */
  334.  for(i=0;i<10;i++) if(strcmp(BaudRate[i],P)==0) return(i);
  335.  return(-1);
  336. }
  337.  
  338. void CheckOverrun(int Port)
  339. {
  340.  if(OverrunError&SioLine(Port))  printf("!!! COM%d overrun error !!!\n", 1+Port);
  341. }
  342.  
  343. void ShowStats(int Port)
  344. {printf("COM%d: %d TX interrupts, %d RX interrupts\n",
  345.          1+Port,SioStats(Port,'T'),SioStats(Port,'R') );
  346.  printf("COM%d: %d TX bytes kickstarted, %d bytes trans by ISR\n",
  347.          1+Port,SioStats(Port,'K'),SioStats(Port,'C') );
  348. }
  349.